//
//  LMSectionBaseViewModel.m
//  AFNetworking
//
//  Created by Arc Lin on 2021/2/8.
//  Copyright © 2021 广东灵机文化传播有限公司（本内容仅限于广东灵机文化传播有限公司内部传阅，禁止外泄以及用于其他的商业目的）. All rights reserved.
//

#import "YKSectionBaseViewModel.h"
#import "YKSectionViewModelProtocol.h"
#import "YKSectionResuseViewInfo.h"

@interface YKSectionBaseViewModel()

@property (nonatomic, strong) NSArray<id<YKSectionViewModelProtocol>> *viewModels;

@property (nonatomic, strong) NSArray<id<YKSectionViewModelProtocol>> *showingViewModels;

@property (nonatomic, strong) NSArray<NSArray *> *dataSources;

@property (nonatomic, strong) NSArray *cellInfos;

@property (nonatomic, strong) NSArray *sectionHeaderViewInfos;

@property (nonatomic, strong) NSArray *sectionFooterViewInfos;

@property (nonatomic, strong) RACSubject *reloadSubject;

@property (nonatomic, strong) RACSubject<NSError *> *errorSubject;

@property (nonatomic, strong) NSArray<RACCommand *> *commands;

@property (nonatomic, strong) RACDisposable *mergeExecuteDisposable;

@end

@implementation YKSectionBaseViewModel

- (instancetype)initWithSectionViewModels:(NSArray<id<YKSectionViewModelProtocol>> *)sectionViewModels
{
    if (self = [super init]) {
        self.viewModels = sectionViewModels;
        [self setup:YES];
    }
    return self;
}

- (void)setup:(BOOL)needRequest
{
    NSMutableArray *commands = [NSMutableArray array];
    NSMutableArray *signals = [NSMutableArray array];
    NSMutableArray *errors = [NSMutableArray array];
    NSMutableArray *cellInfos = [NSMutableArray array];
    NSMutableArray *sectionHeaderInfos = [NSMutableArray array];
    NSMutableArray *sectionFooterInfos = [NSMutableArray array];
    
    for (id<YKSectionViewModelProtocol> viewModel in self.viewModels) {
        [commands addObjectsFromArray:[viewModel yk_executeCommands]?:@[]];
        [cellInfos addObjectsFromArray:[viewModel yk_cellNames]?:@[]];
        if ([viewModel respondsToSelector:@selector(yk_sectionHeaderName)]) {
            YKSectionResuseViewInfo *info = [viewModel yk_sectionHeaderName];
            if (info) {
                [sectionHeaderInfos addObject:info];
            }
        }
        if ([viewModel respondsToSelector:@selector(yk_sectionFooterName)]) {
            YKSectionResuseViewInfo *info = [viewModel yk_sectionFooterName];
            if (info) {
                [sectionFooterInfos addObject:info];
            }
        }
    }
    self.cellInfos = [cellInfos.rac_sequence map:^id _Nullable(YKSectionResuseViewInfo * _Nullable value) {
        return @{className:value.className?:@"",idName:value.reuseViewId?:@""};
    }].array;
    self.sectionHeaderViewInfos = [sectionHeaderInfos.rac_sequence map:^id _Nullable(YKSectionResuseViewInfo * _Nullable value) {
        return @{className:value.className?:@"",idName:value.reuseViewId?:@""};
    }].array;
    self.sectionFooterViewInfos = [sectionFooterInfos.rac_sequence map:^id _Nullable(YKSectionResuseViewInfo * _Nullable value) {
        return @{className:value.className?:@"",idName:value.reuseViewId?:@""};
    }].array;
    
    for (RACCommand *command in commands) {
        [signals addObject:command.executionSignals.switchToLatest];
        [errors addObject:command.errors];
    }
    
    @weakify(self);
    
    if (self.mergeExecuteDisposable) {
        [self.mergeExecuteDisposable dispose];
    }
    
    self.mergeExecuteDisposable = [[RACSignal merge:signals] subscribeNext:^(id  _Nullable x) {
        @strongify(self);
        [self reloadData];
    }];
    
    [[RACSignal merge:errors] subscribe:self.errorSubject];
    
    if (needRequest) {
        [commands makeObjectsPerformSelector:@selector(execute:) withObject:nil];
    } else {
        [self reloadData];
    }
    self.commands = commands;
}

- (void)reloadData {
    NSMutableArray *datasSource = [NSMutableArray array];
    NSMutableArray *showingViewModels = [NSMutableArray array];
    for (id<YKSectionViewModelProtocol> viewModel in self.viewModels) {
        NSArray *data = [viewModel yk_dataSource];
        BOOL showHeader = NO;
        if ([viewModel respondsToSelector:@selector(yk_showHeaderWhenNoData)]) {
            showHeader = [viewModel yk_showHeaderWhenNoData];
        }
        if (showHeader || (data && data.count > 0)) {
            [showingViewModels addObject:viewModel];
        }
        if (showHeader && (!data || data.count == 0)) {
            [datasSource addObject:@[]];
        }
        if (data && data.count > 0) {
            [datasSource addObject:data];
        }
    }
    // showingViewMoel和dataSources的下标是对应的
    self.showingViewModels = showingViewModels;
    self.dataSources = datasSource;
    [self.reloadSubject sendNext:nil];
}

- (void)reloadDataAtSection:(NSIndexSet *)indexSet {
    [indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
        if (idx < self.viewModels.count) {
            id<YKSectionViewModelProtocol> viewModel = self.viewModels[idx];
            [viewModel.yk_executeCommands makeObjectsPerformSelector:@selector(execute:) withObject:nil];
        }
    }];
}

- (void)resetSectionViewModels:(NSArray<id<YKSectionViewModelProtocol>> *)viewModels needRequest:(BOOL)needRequest {
    self.viewModels = viewModels;
    [self setup:needRequest];
}

- (void)insertSectionViewModel:(id<YKSectionViewModelProtocol>)viewModel atIndex:(NSInteger)index {
    NSMutableArray *arr = self.viewModels.mutableCopy;
    if (index > self.viewModels.count) return;
    [arr insertObject:viewModel atIndex:index];
    self.viewModels = arr;
    [self setup:NO];
    for (RACCommand *command in viewModel.yk_executeCommands) {
        [command execute:nil];
    }
}

- (void)deleteSectionViewModel:(id<YKSectionViewModelProtocol>)viewModel {
    NSMutableArray *arr = self.viewModels.mutableCopy;
    if (![arr containsObject:viewModel]) return;
    [arr removeObject:viewModel];
    self.viewModels = arr;
    [self reloadData];
}

- (NSString *)cellIdAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellId = [self.showingViewModels[indexPath.section] yk_cellIdAtIndexPath:indexPath];
    return cellId;
}

- (void)didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self.showingViewModels[indexPath.section] respondsToSelector:@selector(yk_isRowSelectableAtIndexPath:)]) {
        BOOL selectable = [self.showingViewModels[indexPath.section] yk_isRowSelectableAtIndexPath:indexPath];
        if (!selectable) {
            return;
        }
    }
    if ([self.showingViewModels[indexPath.section] respondsToSelector:@selector(yk_didSelectItemAtIndexPath:complete:)]) {
        @weakify(self);
        [self.showingViewModels[indexPath.section] yk_didSelectItemAtIndexPath:indexPath complete:^(UIViewController *controller, YKSectionCollectionViewPushType type) {
            @strongify(self);
            if (!controller) return;
            if (self.handleViewController) {
                self.handleViewController(controller, type);
            }
        }];
    }
}

- (BOOL)handleRouterEvent:(NSString *)eventName userInfo:(NSDictionary *)userInfo handleController:(void(^)(UIViewController * controller,YKSectionCollectionViewPushType pushType))handleControllerBlock
{
    BOOL flag = NO;
    for (id<YKSectionViewModelProtocol> viewModel in self.showingViewModels) {
        if ([viewModel respondsToSelector:@selector(yk_handleRouterEvent:userInfo:controllerEvent:)]) {
            flag = [viewModel yk_handleRouterEvent:eventName userInfo:userInfo controllerEvent:handleControllerBlock] || flag;
        }
    }
    return flag;
}

- (RACSubject *)reloadSubject
{
    if (!_reloadSubject) {
        _reloadSubject = [RACSubject subject];
    }
    return _reloadSubject;
}

- (RACSubject<NSError *> *)errorSubject
{
    if (!_errorSubject) {
        _errorSubject = [RACSubject subject];
    }
    return _errorSubject;
}

- (void)dealloc {
    
}

@end
